package com.tms.security.config;

import com.alibaba.fastjson.JSON;
import com.tms.utils.Data;
import com.tms.utils.JsonResult;
import com.tms.utils.token.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;


/**
 * spring security处理器
 *
 * @author ozj
 */
@Configuration
public class SecurityHandlerConfig {

    @Autowired
    private TokenService tokenService;

    /**
     * 登陆成功，返回Token
     *
     * @return
     */
    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> {
            String token = tokenService.getTokenFromAuthentication(authentication);
            JsonResult jsonResult = new JsonResult("success", "登录成功。", new Data(token, tokenService.getUserByToken(token)));
            response.setContentType("application/json;charset=utf-8");
            response.setHeader("token", token);
            PrintWriter out = response.getWriter();
            out.write(JSON.toJSONString(jsonResult));
            out.flush();
            out.close();
        };
    }

    /**
     * 登陆失败
     *
     * @return
     */
    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) -> {
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            PrintWriter out = response.getWriter();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 401);
            if (exception instanceof UsernameNotFoundException || exception instanceof BadCredentialsException) {
                map.put("message", "用户名或密码错误");
            } else if (exception instanceof DisabledException) {
                map.put("message", "账户被禁用");
            } else {
                map.put("message", "登录失败!");
            }
            out.write(JSON.toJSONString(map));
            out.flush();
            out.close();
        };

    }

    /**
     * 未登录，返回401
     *
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, authException) -> {
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            PrintWriter out = response.getWriter();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 401);
            map.put("message", "未登录");
            out.write(JSON.toJSONString(map));
            out.flush();
            out.close();
        };
    }

    /**
     * 退出处理
     *
     * @return
     */
    @Bean
    public LogoutSuccessHandler logoutSussHandler() {
        return (request, response, authentication) -> {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 200);
            map.put("message", "退出成功");
            map.put("data", authentication);
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.write(JSON.toJSONString(map));
            out.flush();
            out.close();
        };

    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, ex) -> {
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            PrintWriter out = response.getWriter();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 403);
            map.put("status", "failed");
            map.put("description", "权限不足");
            out.write(JSON.toJSONString(map));
            out.flush();
            out.close();
        };
    }

    public AuthenticationEntryPoint getAauthenticationEntryPoint() {
        return (req, resp, authException) -> {
            resp.setContentType("application/json;charset=utf-8");
            resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
            PrintWriter out = resp.getWriter();
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 403);
            map.put("status", "failed");
            map.put("description", "权限不足");
            out.write(JSON.toJSONString(map));
            out.flush();
            out.close();
        };
    }
}
